package app.vendorportal;

import app.vendorportal.web.interceptor.LoginRequiredInterceptor;
import app.vendorportal.web.interceptor.MasterLayout;
import app.vendorportal.web.interceptor.MasterTemplateModelBuilder;
import app.vendorportal.web.interceptor.VendorPermissionInterceptor;
import core.framework.log.LogSettings;
import core.framework.web.DefaultSiteConfig;
import core.framework.web.runtime.RuntimeEnvironment;
import core.framework.web.runtime.RuntimeSettings;
import core.framework.web.site.SiteSettings;
import core.framework.web.site.layout.ModelBuilderInterceptor;
import core.framework.web.site.session.SessionProviderType;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;

@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@ComponentScan(basePackageClasses = WebConfig.class)
public class WebConfig extends DefaultSiteConfig {
    @Inject
    Environment env;
    @Inject
    EntityManagerFactory entityManagerFactory;

    @Override
    public RuntimeSettings runtimeSettings() {
        RuntimeSettings settings = super.runtimeSettings();
        settings.setEnvironment(env.getProperty("site.environment", RuntimeEnvironment.class, RuntimeEnvironment.PROD));
        settings.setVersion(version());
        return settings;
    }

    @Override
    public LogSettings logSettings() {
        LogSettings config = super.logSettings();
        //config.filterLog(new VendorPortalLogMessageFilter());
        return config;
    }

    private String version() {
        String version = env.getProperty("runtime.version");
        if (!StringUtils.hasText(version) || version.contains("${"))
            return "current"; // for local build, where version is not populated by build
        return version;
    }

    @Override
    public SiteSettings siteSettings() {
        SiteSettings settings = new SiteSettings();
        settings.setErrorPage("/error");
        settings.setResourceNotFoundPage("forward:/error/resource-not-found");
        settings.setSessionTimeOutPage("redirect:/login");
        settings.setSessionProviderType(env.getProperty("site.sessionProvider", SessionProviderType.class, SessionProviderType.LOCAL));
        settings.setRemoteSessionServer(env.getProperty("site.remoteSessionServer"));
        settings.setJSDir("/static/js");
        settings.setCSSDir("/static/css");
        //settings.setCustomTagSupport(VendorPortalTagSupport.class);
        return settings;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(exceptionInterceptor());
        //registry.addInterceptor(multiPartCastInterceptor());
        registry.addInterceptor(requestContextInterceptor());
        OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor = new OpenEntityManagerInViewInterceptor();
        openEntityManagerInViewInterceptor.setEntityManagerFactory(entityManagerFactory);
        registry.addWebRequestInterceptor(openEntityManagerInViewInterceptor);
        registry.addInterceptor(httpSchemeEnforceInterceptor());
        registry.addInterceptor(cookieInterceptor());
        registry.addInterceptor(sessionInterceptor());
        registry.addInterceptor(loginRequiredInterceptor());
        registry.addInterceptor(modelBuilderInterceptor());
        registry.addInterceptor(vendorPermissionInterceptor());
    }


    @Bean
    public LoginRequiredInterceptor loginRequiredInterceptor() {
        return new LoginRequiredInterceptor();
    }

    @Bean
    public ModelBuilderInterceptor modelBuilderInterceptor() {
        ModelBuilderInterceptor interceptor = new ModelBuilderInterceptor();
        interceptor.registerModelBuilder(MasterLayout.class, MasterTemplateModelBuilder.class);
        return interceptor;
    }

    @Bean
    VendorPermissionInterceptor vendorPermissionInterceptor() {
        return new VendorPermissionInterceptor();
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("forward:/login");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // on server env, /mstatic will be handled by apache or CDN, this only apply to local dev
        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
        registry.addResourceHandler("/favicon.ico").addResourceLocations("/static/");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }

    @Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(300000000); // 300M limit for big
        // excel files
        return multipartResolver;
    }

}
